package util

import (
	"bufio"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/natefinch/lumberjack"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
	"gopkg.in/yaml.v2"
	"io/ioutil"
	"os"
	"time"
)

const (
	ErrorCode   = 40003
	SuccessCode = 0
	Online      = 1
	Offline     = -1
)

var Logger *zap.Logger
var Configs *Config
var Whitelist []string
var configFilePath string = "./conf/config.yaml"
var whiteFilePath string = "./conf/whitelist.yaml"
var RemoteControl bool // 远程控制开关
var CstZone, _ = time.LoadLocation("Asia/Shanghai")

//配置参数
type Config struct {
	//运行模式 debug/release
	RunMode string `yaml:"runMode"`
	Host    string `yaml:"host"`
	//默认 :8080
	Port string `yaml:"port"`
	//数据库配置信息
	Database struct {
		Network1 string `yaml:"network1"`
		Singular bool   `yaml:"singular"`
	} `yaml:"database"`
	Ffmpeg struct {
		Path string `yaml:"path"`
	}
}

//输出消息体

type ReturnResultMsgType struct {
	Result      string      `json:"result"`
	Description string      `json:"description"`
	Code        int         `json:"code"`
	Data        interface{} `json:"data,string"`
}

func init() {
	GetConf()
	GetWhite()
	initLog()
	RemoteControl = false
	// initDbConnect()
}

func GetConf() *Config {
	yamlFile, err := ioutil.ReadFile(configFilePath)
	if err != nil {
		fmt.Println(err.Error())
	}
	err = yaml.Unmarshal(yamlFile, &Configs)
	if err != nil {
		fmt.Println(err.Error())
	}
	return Configs
}

// 获取白名单

func GetWhite() []string {
	Whitelist = append(Whitelist, "127.0.0.1")
	Whitelist = append(Whitelist, "localhost")
	Whitelist = append(Whitelist, "::1")
	wfile, err := os.Open(whiteFilePath)
	if err != nil {
		fmt.Println(err.Error())
		return Whitelist
	}
	defer wfile.Close()
	scanner := bufio.NewScanner(wfile)
	for scanner.Scan() {
		Whitelist = append(Whitelist, scanner.Text())
	}
	if err = scanner.Err(); err != nil {
		fmt.Println(err.Error())
		return Whitelist
	}
	return Whitelist
}

func initLog() {

	now := time.Now()
	hook := &lumberjack.Logger{
		Filename:   fmt.Sprintf("./runtime/logs/%04d-%02d-%02d-%02d%02d%02d.log", now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute(), now.Second()), //filePath
		MaxSize:    500,                                                                                                                                       // megabytes
		MaxBackups: 10000,
		MaxAge:     100000, //days
		Compress:   false,  // disabled by default
	}
	defer hook.Close()
	/*zap 的 Config 非常的繁琐也非常强大，可以控制打印 log 的所有细节，因此对于我们开发者是友好的，有利于二次封装。
	  但是对于初学者则是噩梦。因此 zap 提供了一整套的易用配置，大部分的姿势都可以通过一句代码生成需要的配置。
	*/
	enConfig := zap.NewProductionEncoderConfig() //生成配置

	// 时间格式
	enConfig.EncodeTime = zapcore.ISO8601TimeEncoder

	level := zap.InfoLevel
	w := zapcore.AddSync(hook)
	core := zapcore.NewCore(
		zapcore.NewConsoleEncoder(enConfig), //编码器配置
		w,                                   //打印到控制台和文件
		level,                               //日志等级
	)

	Logger = zap.New(core, zap.AddCaller(), zap.AddCallerSkip(1))

}

func GetLogger(ctx *gin.Context) *zap.Logger {
	_log, ok := ctx.Get("logger")
	if ok == false {
		Logger.Error("get logger error")
	}
	return _log.(*zap.Logger)
}
